﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.Collections;
using System.Web;
using System.IO;
using Silmoon;
using System.Collections.Specialized;

namespace cklib
{
    [Serializable()]
    public class CookyDNSAPI
    {
        protected internal string _baseAPIUri = "http://localhost:8081/cookydns-webmanager/API.ashx";
        string _username;
        string _password;
        string _token;
        bool _isLogin = false;
        string _user_agent = "unnamed_cklib/0.0.0.1";
        public string LastServerResult = "";
        public string LastMessage = "";
        public int LastStatusCode = -9990;
        int _userID = 0;
        public bool _blackCase = false;
        public string ValidateFrom = "";
        public ArrayList APIHeaders = new ArrayList();

        NameValueCollection allServerNetmarks = null;
        public bool BlackCase
        {
            get { return _blackCase; }
            set { _blackCase = value; }
        }
        /// <summary>
        /// 获取状态是否是已经登录
        /// </summary>
        public bool IsLogin
        {
            get { return _isLogin; }
            private set { _isLogin = value; }
        }
        /// <summary>
        /// 获取或设置当前用户名
        /// </summary>
        public string Username
        {
            get { return _username; }
            set { _username = value; }
        }
        /// <summary>
        /// 获取或设置用户密码
        /// </summary>
        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }
        /// <summary>
        /// 设置暗箱操作使用的Token
        /// </summary>
        public string Token
        {
            get { return _token; }
            private set { _token = value; }
        }
        /// <summary>
        /// 获取或设置CookyDNS API路径
        /// </summary>
        public string BaseAPIUri
        {
            get { return _baseAPIUri; }
            set { _baseAPIUri = value; }
        }
        /// <summary>
        /// 获取UA
        /// </summary>
        public string User_Agent
        {
            get { return _user_agent; }
        }
        /// <summary>
        /// 获取用户ID
        /// </summary>
        public int UserID
        {
            get { return _userID; }
            set { _userID = value; }
        }
        /// <summary>
        /// 获取当前所有线路的标记
        /// </summary>
        public NameValueCollection AllServerNetmarks
        {
            get
            {
                if (allServerNetmarks == null || allServerNetmarks.Count == 0)
                    allServerNetmarks = (NameValueCollection)GetNetworkMarks().Data;
                return allServerNetmarks;
            }
        }

        /// <summary>
        /// 类型构造器
        /// </summary>
        public CookyDNSAPI()
        {

        }
        /// <summary>
        /// 类型构造器，指定使用的UA
        /// </summary>
        /// <param name="user_agent"></param>
        public CookyDNSAPI(string user_agent)
        {
            _user_agent = user_agent;
        }

        /// <summary>
        /// 向服务器发送POST请求
        /// </summary>
        /// <param name="actionName">API字段</param>
        /// <param name="data">POST数据</param>
        /// <returns>服务器返回的数据</returns>
        public string GetXml(string actionName, string data)
        {
            WebClient _wclit = new WebClient();
            try
            {
                _wclit.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                _wclit.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
                foreach (string s in APIHeaders)
                    _wclit.Headers.Add(s);
                _wclit.Headers.Add("User-Agent", "(SM)" + _user_agent);

                Uri uri = new Uri(_baseAPIUri + "?apitype=dns&action=" + actionName + "&" + data);
                byte[] getData = _wclit.DownloadData(uri);
                string result = Encoding.UTF8.GetString(getData);
                _wclit.Dispose();
                return result;
            }
            catch (WebException ex)
            {
                try
                {
                    File.WriteAllText(@"C:\CookyDNS_Network_Error.xml.txt", DateTime.Now + "\r\n\r\n" + ex + "\r\n\r\n");
                    if (ex.Response != null)
                        File.AppendAllText(@"C:\CookyDNS_Network_Error.xml.txt", new StreamReader(ex.Response.GetResponseStream()).ReadToEnd());
                }
                catch { }
                _wclit.Dispose();
                return "!" + ex.ToString();
            }
        }

        /// <summary>
        /// 指定使用的UA
        /// </summary>
        /// <param name="user_agent"></param>
        public void SetUserAgent(string user_agent)
        {
            _user_agent = user_agent;
        }
        /// <summary>
        /// 指定CookyDNS API路径
        /// </summary>
        /// <param name="apiUrl"></param>
        public void SetAPIUrl(string apiUrl)
        {
            _baseAPIUri = apiUrl;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public UserResult Login(string username, string password)
        {
            BlackCase = false;

            _username = username;
            _password = password;
            return GetUserInfo();
        }
        /// <summary>
        /// 设置登录状态
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="login">是否设置为已经登录</param>
        public void SetLoginState(string username, string password, bool login)
        {
            BlackCase = false;
            _username = username;
            _password = password;
            _isLogin = login;
        }
        /// <summary>
        /// 黑箱操作登录
        /// </summary>
        /// <param name="token">TOKEN</param>
        /// <param name="validate">是否验证TOKEN</param>
        public UserResult BlackCaseLogin(int userID, string token, bool validate = false)
        {
            BlackCase = true;
            UserID = userID;
            Token = token;
            if (validate)
            {
                return GetUserInfo();
            }
            return null;
        }
        /// <summary>
        /// 设置登录状态
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <param name="login">是否设置为已经登录</param>
        public void SetBlackLoginState(int userID, string token, bool login)
        {
            BlackCase = true;
            UserID = userID;
            Token = token;
            _isLogin = login;
        }

        /// <summary>
        /// 获取用户指定类型的域名
        /// </summary>
        /// <param name="type">域名所属类型</param>
        /// <returns></returns>
        public DomainsResult GetDomains(DomainListType type = DomainListType.all)
        {
            DomainsResult result = new DomainsResult();
            XmlDocument xmlDoc = new XmlDocument();

            string resultXml = GetXml("getdomainlist", AuthConnection() + "&type=" + type.ToString());

            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1, 9 });
                ArrayList binfoArr = new ArrayList();
                if (result.Success)
                {
                    XmlNode domainsNode = xmlDoc["CookyDNS"]["Data"]["Domains"];
                    if (domainsNode != null)
                    {
                        foreach (XmlNode node in domainsNode)
                        {
                            Domain newInfo = new Domain();
                            newInfo.DomainName = node["DomainName"].InnerText;
                            newInfo.State = node["Status"].InnerText;
                            newInfo.Records = int.Parse(node["Records"].InnerText);
                            newInfo.ID = 0;
                            newInfo.Grade = StringToGrade(node["Grade"].InnerText);
                            if (node["shared_from"] != null)
                                newInfo.ShardForm = node["shared_from"].InnerText;
                            newInfo.Validate = CookyValidateInfo.FromCooky;
                            binfoArr.Add(newInfo);
                        }
                    }
                }
                result.Domains = (Domain[])binfoArr.ToArray(typeof(Domain));
            }
            return result;
        }
        /// <summary>
        /// 获取用户域名记录
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <returns>域名记录数组</returns>
        public RecordsResult GetRecords(string domain)
        {
            XmlDocument xmlDoc = new XmlDocument();
            RecordsResult result = new RecordsResult();
            string resultXml = GetXml("getrecordlist", AuthConnection() + "&domain=" + domain);

            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1, 10 });
                if (result.Success)
                {
                    ArrayList array = new ArrayList();
                    XmlNode recordsNode = xmlDoc["CookyDNS"]["Data"]["Records"];
                    if (recordsNode != null)
                    {
                        foreach (XmlNode node in recordsNode)
                        {
                            Record newRecord = new Record();
                            //newRecord.Enable = SmString.StringToBool(node["enabled"].InnerText);
                            newRecord.ID = node["_ID"].InnerText;
                            newRecord.Netmark = node["Netmark"].InnerText;
                            newRecord.MXLevel = int.Parse(node["MXLevel"].InnerText);
                            newRecord.Subname = node["Host"].InnerText;
                            newRecord.TTL = int.Parse(node["TTL"].InnerText);
                            newRecord.Type = (DNS_TYPE)int.Parse(node["Type"].InnerText);
                            newRecord.Value = node["Value"].InnerText;
                            newRecord.State = node["State"].InnerText;
                            newRecord.Validate = CookyValidateInfo.FromCooky;
                            array.Add(newRecord);
                        }
                    }
                    result.Records = (Record[])array.ToArray(typeof(Record));
                }
            }
            return result;
        }
        /// <summary>
        /// 从域名ID和记录ID获取记录信息
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <param name="recordID">记录ID</param>
        /// <returns></returns>
        public RecordResult GetRecord(int domainID, int recordID)
        {
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                RecordResult result = new RecordResult();
                string resultXml = GetXml("Record.Info", AuthConnection() + "&domain_id=" + domainID + "&record_id=" + recordID);

                if (LoadXml(ref resultXml, result, ref xmlDoc) && ProcessBaseXml(result, ref xmlDoc, new int[] { 1 }))
                {
                    if (!result.Success)
                    {
                        XmlNode node = xmlDoc["Cooky"]["record"];
                        result.Record = new Record();
                        result.Record.State = node["state"].InnerText;
                        result.Record.ID = node["id"].InnerText;
                        result.Record.Subname = node["sub_domain"].InnerText;
                        result.Record.Netmark = node["record_line"].InnerText;
                        result.Record.Type = (DNS_TYPE)int.Parse(node["record_type"].InnerText);
                        result.Record.Validate = CookyValidateInfo.FromCooky;
                        result.Record.Value = node["value"].InnerText;
                        result.Record.MXLevel = int.Parse(node["mx"].InnerText);
                        result.Record.TTL = int.Parse(node["ttl"].InnerText);
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 从记录数组中获取一个记录的信息。
        /// </summary>
        /// <param name="records">记录数组</param>
        /// <param name="recordID">记录ID</param>
        /// <returns></returns>
        public Record GetRecord(Record[] records, string recordID)
        {
            foreach (Record record in records)
            {
                if (record.ID == recordID)
                    return record;
            }
            return null;
        }
        /// <summary>
        /// 设置域名状态
        /// </summary>
        /// <param name="domain">域名ID</param>
        /// <param name="enable">是否启用</param>
        /// <returns></returns>
        public CookyResult SetDomainState(string domain, bool enable)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string domainAction = "";
            if (enable) domainAction = "enabledomain"; else domainAction = "disabledomain";
            string resultXml = GetXml(domainAction, AuthConnection() + "&domain=" + domain);

            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 添加域名
        /// </summary>
        /// <param name="domain">要添加的域名</param>
        /// <returns></returns>
        public CookyResult CreateDomain(string domain)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string resultXml = GetXml("createdomain", AuthConnection() + "&domain=" + domain);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 删除域名
        /// </summary>
        /// <param name="domainID">要删除的域名ID</param>
        /// <returns></returns>
        public CookyResult RemoveDomain(string domain)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string resultXml = GetXml("removedomain", AuthConnection() + "&domain=" + domain);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 添加记录
        /// </summary>
        /// <param name="record">域名记录信息</param>
        /// <param name="domainID">域名ID</param>
        /// <returns>状态集</returns>
        public CookyResult CreateRecord(Record record, string domain)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string urlArgs = AuthConnection();
            urlArgs += "&domain=" + domain;
            urlArgs += "&host=" + record.Subname;
            urlArgs += "&type=" + (int)record.Type;
            urlArgs += "&netmark=" + record.Netmark.ToString().ToLower();
            urlArgs += "&value=" + HttpUtility.UrlEncode(record.Value);
            urlArgs += "&mxlevel=" + record.MXLevel;
            urlArgs += "&ttl=" + record.TTL;
            string resultXml = GetXml("createrecord", urlArgs);
            LoadXml(ref resultXml, result, ref xmlDoc);
            ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 编辑域名记录
        /// </summary>
        /// <param name="record">域名记录信息</param>
        /// <param name="domainID">域名ID</param>
        /// <returns>状态集</returns>
        public CookyResult ModifyRecord(Record record, string domainid)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string urlArgs = AuthConnection();
            urlArgs += "&id=" + domainid;
            urlArgs += "&host=" + record.Subname;
            urlArgs += "&type=" + (int)record.Type;
            urlArgs += "&netmark=" + record.Netmark.ToString().ToLower();
            urlArgs += "&value=" + HttpUtility.UrlEncode(record.Value);
            urlArgs += "&mxlevel=" + record.MXLevel;
            urlArgs += "&ttl=" + record.TTL;
            urlArgs += "&from=" + ValidateFrom;
            string resultXml = GetXml("updaterecord", urlArgs);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 删除域名记录
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <param name="recordID">记录ID</param>
        /// <returns>结果集</returns>
        public CookyResult RemoveRecord(string recordID)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string resultXml = GetXml("removerecord", AuthConnection() + "&id=" + recordID);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }
        /// <summary>
        /// 设置域名记录状态
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <param name="recordID">记录ID</param>
        /// <param name="enable">是否启用</param>
        /// <returns>结果集</returns>
        public CookyResult SetRecordState(string recordID, bool enable)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();

            string resultXml = "";
            if(enable)
                resultXml = GetXml("enablerecord", AuthConnection() + "&id=" + recordID);
            else
                resultXml = GetXml("disablerecord", AuthConnection() + "&id=" + recordID);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
            return result;
        }

        /// <summary>
        /// 获取域名信息
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <returns>域名信息</returns>
        public DomainResult GetDomainInfo(int domainID)
        {
            XmlDocument xmlDoc = new XmlDocument();
            DomainResult result = new DomainResult();
            string resultXml = GetXml("Domain.Info", AuthConnection() + "&domain_id=" + domainID);

            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
                if (!result.Success)
                {
                    result.Domain = new Domain();
                    XmlNode recordsNode = xmlDoc["Cooky"]["domain"];

                    result.Domain.DomainName = recordsNode["name"].InnerText;
                    result.Domain.Grade = StringToGrade(recordsNode["grade"].InnerText);
                    result.Domain.ID = int.Parse(recordsNode["id"].InnerText);
                    result.Domain.Records = int.Parse(recordsNode["records"].InnerText);
                    result.Domain.State = recordsNode["status"].InnerText;
                    //domain.ShardForm = int.Parse(node["ttl"].InnerText);
                    result.Domain.Validate = CookyValidateInfo.FromCooky;
                }
                return result;
            }
            return result;
        }
        /// <summary>
        /// 获取域名信息从域名信息数组中
        /// </summary>
        /// <param name="domainID">域名ID</param>
        /// <param name="domains">域名信息数组</param>
        /// <returns>域名信息</returns>
        public Domain GetDomainInfo(int domainID, Domain[] domains)
        {
            foreach (Domain domain in domains)
            {
                if (domain.ID == domainID)
                    return domain;
            }
            return null;
        }
        /// <summary>
        /// 获取域名信息
        /// </summary>
        /// <param name="domain">域名</param>
        /// <returns>域名信息</returns>
        public DomainResult GetDomainInfo(string domain)
        {
            DomainResult result = new DomainResult();
            DomainsResult domains = GetDomains();
            result.IntFlag = domains.IntFlag;
            result.Message = domains.Message;
            result.XML = domains.XML;
            result.Success = domains.Success;

            if (domains.Success) return result;
            foreach (Domain domainInfo in domains.Domains)
            {
                if (domainInfo.DomainName.ToLower() == domain.ToLower())
                    result.Domain = domainInfo;
            }
            return result;
        }
        /// <summary>
        /// 获取域名信息从域名信息数组中
        /// </summary>
        /// <param name="domain">域名</param>
        /// <param name="domains">域名信息数组</param>
        /// <returns>域名信息</returns>
        public Domain GetDomainInfo(string domain, Domain[] domains)
        {
            foreach (Domain domainInfo in domains)
            {
                if (domainInfo.DomainName.ToLower() == domain.ToLower())
                    return domainInfo;
            }
            return null;
        }

        public DetailResult GetUserDetail(int userID = 0)
        {
            DetailResult result = new DetailResult();
            XmlDocument xml = new XmlDocument();
            string resultXml = null;
            if (userID == 0) resultXml = GetXml("User.Detail", AuthConnection() + "&user_id=" + userID);
            else resultXml = GetXml("User.Detail", AuthConnection());
            if (LoadXml(ref resultXml, result, ref xml))
            {
                ProcessBaseXml(result, ref xml, new int[] { 1 });
                if (!result.Success)
                {
                    result.Detail = new CookyUserDetail();
                    result.Detail.Email = xml["Cooky"]["info"]["user"]["email"].InnerText;
                    result.Detail.FetionNumber = xml["Cooky"]["info"]["user"]["ftmobi"].InnerText;
                    result.Detail.FetionPassword = xml["Cooky"]["info"]["user"]["ftpass"].InnerText;
                    result.Detail.IM = xml["Cooky"]["info"]["user"]["im"].InnerText;
                    result.Detail.Realname = xml["Cooky"]["info"]["user"]["real_name"].InnerText;
                    result.Detail.Telephone = xml["Cooky"]["info"]["user"]["telephone"].InnerText;
                    result.Detail.UserType = xml["Cooky"]["info"]["user"]["user_type"].InnerText;
                    result.Detail.Website = xml["Cooky"]["info"]["user"]["website"].InnerText;

                    result.Detail.Balance = double.Parse(xml["Cooky"]["info"]["user"]["balance"].InnerText);

                    if (xml["Cooky"]["info"]["agent"] != null)
                    {
                        result.Detail.Discount = int.Parse(xml["Cooky"]["info"]["agent"]["discount"].InnerText);
                        result.Detail.Points = int.Parse(xml["Cooky"]["info"]["agent"]["points"].InnerText);
                        result.Detail.AgentUsers = int.Parse(xml["Cooky"]["info"]["agent"]["users"].InnerText);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        public UserResult GetUserInfo()
        {
            XmlDocument xmlDoc = new XmlDocument();
            UserResult result = new UserResult();
            string resultXml = GetXml("getuserinfo", AuthConnection());
            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                result.User = new CookyUser();

                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
                if (result.Success)
                {
                    result.User.LoginOK = true;
                    IsLogin = true;
                    result.User.Username = xmlDoc["CookyDNS"]["Data"]["Username"].InnerText;
                    Username = result.User.Username;
                }
                else
                {
                    result.User.LoginOK = false;
                    IsLogin = false;
                }
            }

            return result;
        }
        /// <summary>
        /// 获取用户TOKEN
        /// </summary>
        /// <param name="userID">如果是管理员模式，可以获取任意用户的TOKEN，选填此项</param>
        /// <returns></returns>
        public CookyResult GetUserToken(int userID = 0)
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string userIDURlStr = "";
            if (userID != 0) userIDURlStr = "&user_id=" + userID;
            string resultXml = GetXml("User.Token", AuthConnection() + userIDURlStr);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
                if (!result.Success)
                {
                    result.Data = xmlDoc["Cooky"]["user"]["login_token"].InnerText;
                    _token = result.Data.ToString();
                }
            }
            return result;
        }
        /// <summary>
        /// 获取Cooky一次性密码
        /// </summary>
        /// <returns>一次性密码</returns>
        public CookyResult GetOncePassword()
        {
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();
            string resultXml = GetXml("Login.Key", AuthConnection());
            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
                result.Data = xmlDoc.GetElementsByTagName("key")[0].InnerText;
            }
            return result;
        }
        /// <summary>
        /// 获取域名的可用线路
        /// </summary>
        /// <param name="domainInfo">域名信息</param>
        /// <returns></returns>
        public CookyResult GetNetworkMarks()
        {
            string resultXml = GetXml("getnetmarklist", AuthConnection());
            XmlDocument xmlDoc = new XmlDocument();
            CookyResult result = new CookyResult();

            if (LoadXml(ref resultXml, result, ref xmlDoc))
            {
                ArrayList array = new ArrayList();
                ProcessBaseXml(result, ref xmlDoc, new int[] { 1 });
                XmlNode xmlNode = xmlDoc["CookyDNS"]["Data"]["Netmarks"];
                NameValueCollection data = new NameValueCollection();
                foreach (XmlNode item in xmlNode)
                {
                    data[item["Name"].InnerText] = item["Note"].InnerText;
                }
                result.Data = data;
            }
            return result;
        }
        /// <summary>
        /// 使用管理员权限发送短信
        /// </summary>
        /// <param name="to">目标用户的ID</param>
        /// <param name="body">短信主体</param>
        /// <param name="from">应用名称，如果不对，API可能会拒绝</param>
        /// <returns></returns>
        public CookyResult SendSMS(int to, string body,string from)
        {
            CookyResult result = new CookyResult();
            XmlDocument xmlDoc = new XmlDocument();
            string resultXml = GetXml("Sms.Send", AuthConnection() + "&user_id=" + to + "&body=" + HttpUtility.UrlEncode(body) + "&from=" + from);
            if (LoadXml(ref resultXml, result, ref xmlDoc))
                ProcessBaseXml(result,ref xmlDoc, new int[] { 1 });
            return result;
        }
        

        /// <summary>
        /// Load Xml from string
        /// </summary>
        /// <param name="xmlString">string</param>
        /// <param name="xmlDoc">xml object</param>
        public bool LoadXml(ref string xmlString, CookyResult result, ref XmlDocument xmlDoc)
        {
            bool success = false;
            try
            {
                xmlDoc.LoadXml(xmlString);
                success = true;
                result.XML = xmlString;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.IntFlag = -9999;
                result.Message = ex.ToString();
                result.ObjectReferer = ex;
                success = false;
            }
            return success;
        }
        /// <summary>
        /// 处理Cooky返回的基础数据
        /// </summary>
        /// <param name="result">状态引用</param>
        /// <param name="xmlDoc">XML对象</param>
        /// <param name="noWaringCode">无错的状态数字数组</param>
        /// <returns></returns>
        public bool ProcessBaseXml(CookyResult result, ref XmlDocument xmlDoc, int[] noWaringCode)
        {
            result.Success = false;
            try
            {
                result.IntFlag = int.Parse(xmlDoc["CookyDNS"]["State"]["StateCode"].InnerText);
                result.Message = xmlDoc["CookyDNS"]["State"]["Message"].InnerText;
                result.Success = SmString.StringToBool(xmlDoc["CookyDNS"]["State"]["Success"].InnerText);
                foreach (int item in noWaringCode)
                {
                    if (result.IntFlag == item)
                    {
                        result.Success = true;
                        break;
                    }
                }
                LastMessage = result.Message;
                LastStatusCode = result.IntFlag;
                return true;
            }
            catch
            {
                result.Success = true;
                return false;
            }
        }

        public static DomainGrade StringToGrade(string grade)
        {
            switch (grade.ToLower())
            {
                case "d_free":
                    return DomainGrade.D_Free;
                case "d_express":
                    return DomainGrade.D_Express;
                case "d_plus":
                    return DomainGrade.D_Plus;
                case "d_extra":
                    return DomainGrade.D_Extra;
                case "d_expert":
                    return DomainGrade.D_Expert;
                case "d_ultra":
                    return DomainGrade.D_Ultra;
                default:
                    return DomainGrade.D_Free;
            }
        }

        public string AuthConnection()
        {
            if (BlackCase)
            {
                return "login_id=" + UserID + "&login_token=" + Token + "&format=xml";
            }
            else
            {
                return "u=" + HttpUtility.UrlEncode(_username) + "&p=" + HttpUtility.UrlEncode(_password) + "&format=xml";
            }
        }

        public static DNS_TYPE StringToRecordType(string type)
        {
            switch (type.ToLower())
            {
                case "a":
                    return DNS_TYPE.TYPE_A;
                case "cname":
                    return DNS_TYPE.TYPE_CNAME;
                case "mx":
                    return DNS_TYPE.TYPE_MX;
                case "url":
                    return DNS_TYPE.TYPEx_URL;
                case "ns":
                    return DNS_TYPE.TYPE_NS;
                case "txt":
                    return DNS_TYPE.TYPE_TXT;
                case "aaaa":
                    return DNS_TYPE.TYPE_AAAA;
                case "cn":
                    return DNS_TYPE.TYPE_CNAME;
                case "v6":
                    return DNS_TYPE.TYPE_AAAA;
                default:
                    return DNS_TYPE.TYPE_A;
            }
        }
        public static string RecordTypeToString(DNS_TYPE type)
        {
            switch (type)
            {
                case DNS_TYPE.TYPE_A:
                    return "A";
                case DNS_TYPE.TYPE_CNAME:
                    return "CNAME";
                case DNS_TYPE.TYPE_NS:
                    return "NS";
                case DNS_TYPE.TYPE_AAAA:
                    return "AAAA";
                case DNS_TYPE.TYPE_MX:
                    return "MX";
                case DNS_TYPE.TYPE_TXT:
                    return "TXT";
                case DNS_TYPE.TYPE_SOA:
                    return "SOA";
                default:
                    return "A";
            }
        }

        public string NoteToMark(string note)
        {
            for (int i = 0; i < allServerNetmarks.Count; i++)
            {
                if (allServerNetmarks[i] == note) return allServerNetmarks.GetKey(i);
            }
            return "";
        }
        public enum DomainListType
        {
            all, share, mine
        }
    }
    public class Domain
    {
        public string DomainName;
        public string State;
        public int Records;
        public DomainGrade Grade;
        public int ID;
        public string ShardForm;
        public CookyValidateInfo Validate = CookyValidateInfo.New;
    }
    public class DomainsResult : CookyResult
    {
        public Domain[] Domains;
    }
    public class DomainResult : CookyResult
    {
        public Domain Domain;
    }

    public enum DomainGrade
    {
        D_Free = 0,
        D_Express = 1,
        D_Plus = 2,
        D_Extra = 3,
        D_Expert = 4,
        D_Ultra = 5
    }

    public class Record
    {
        public string ID;
        public string Subname;
        public string Netmark = "default";
        public DNS_TYPE Type;
        public int TTL = 3600;
        public string Value;
        public int MXLevel = 5;
        public string State = "#none";
        public CookyValidateInfo Validate = CookyValidateInfo.New;
        public string Note;
        public Record() { }
        public Record(string subname, string isp, DNS_TYPE type, string value)
        {
            Subname = subname;
            Netmark = isp;
            Type = type;
            Value = value;
        }
        public override string ToString()
        {
            return Subname + "->" + Value;
        }
    }
    public class RecordsResult : CookyResult
    {
        public Record[] Records;
    }
    public class RecordResult : CookyResult
    {
        public Record Record;
    }

    public class CookyUser
    {
        public string Username;
        public bool LoginOK = false;
        public string Message;
    }
    public class CookyUserDetail
    {
        public string Realname;
        public string UserType;
        public string Telephone;
        public string IM;
        public string Website;
        public string FetionNumber;
        public string FetionPassword;
        public double Balance;
        public string Email;
        public int UserID;
        public int Discount;
        public int Points;
        public int AgentUsers;
        public int SMSBalance;
    }
    public class UserResult : CookyResult
    {
        public CookyUser User;
    }
    public class DetailResult : CookyResult
    {
        public CookyUserDetail Detail;
    }

    public enum AgentGrade
    {
        unknown = 0,
        bronze = 1,
        silver = 2,
        gold = 3,
        diamond = 4,
    }

    public enum CookyValidateInfo
    {
        FromCooky,
        Invalid,
        New,
    }

    public class CookyResult
    {
        bool _success = false;
        int _intFlag = -9999;
        string _message = "";
        object _objectReferer = null;
        public string XML = "";
        public object Data;

        #region IStateFlag 成员

        public bool Success
        {
            get
            {
                return _success;
            }
            set
            {
                _success = value;
            }
        }

        public int IntFlag
        {
            get
            {
                return _intFlag;
            }
            set
            {
                _intFlag = value;
            }
        }

        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = value;
            }
        }

        public object ObjectReferer
        {
            get
            {
                return _objectReferer;
            }
            set
            {
                _objectReferer = value;
            }
        }

        #endregion
    }
}